このツールを使って 「マイクロソフト西暦 2000 年対応」 に準拠するアプリケーションを構築できますか?
はい
日付の処理
Visual C++ C ランタイム ライブラリには、日付および時刻計算のための関数が複数あります。これらの関数は、1970 年 1 月 1 日から 2038 年 1 月 18 日まで有効です。これらの関数では、日付および時刻計算でタイム ゾーンと夏時間を考慮することができます。詳しくは、Visual C++ のマニュアルを参照してください。
下 2 桁の西暦の処理
西暦は 1900 年を基準として、1900 からの経過年で表示されます。
Microsoft C ランタイムには、時刻の格納のための 2 つの ANSI-C データ構造があります。
- struct tm
- time_t
ANSI 型: struct tm と time_t
ANSI C 規格では、これらの型、その意味、およびある範囲においてその元となる型を規定しています。Visual C++ では、time_t 型は long であり、この型の変数を利用する ANSI C 関数と共に使用された場合には 1970 年 1 月 1 日からの秒数を表わします。struct tm 型は、日付を構成する各部分を格納するために使用されます。struct tm は、内部変数を使用して、1900 年以降の年数として西暦を保存します。また、現在夏時間が適用されているかどうかだけでなく、月、曜日、月初めからの日数、年初からの日数、時間、分、および秒もこの構造に格納します。これらのメンバーは、int 型です。これらは、時刻の操作、入出力を行うために ANSI 関数が使用する型です。詳しくは、Visual C++ のマニュアルを参照してください。
ANSI 時刻関数での問題の回避
ANSI 関数をそのまま使用すると、アプリケーションで西暦 2000 年問題を起こす可
能性があります。簡単なガイドラインを守ることで、プログラムがあいまいな日付を
出力することを回避して、西暦 2000 年対応のアプリケーションを作成することがで
きます。注意を要するのは、strftime と wcsftime です。
- アプリケーションのユーザーに対して日付を表示するときは、4 桁の西暦を使用します。strftime 関数と wcsftime 関数を使用するときは、下 2 桁の西暦を表示する %y (小文字) ではなく、%Y を使用して 4 桁の西暦を表示します。次の例を参照してください。
#include <time.h>
#include <stdio.h>
const int BUFSIZE = 256;
char buf[BUFSIZE];
int main()
{
struct tm now;
time_t tmp = time(0); // get current time
now = *localtime(&tmp); // get components
// 2-digit vs. 4-digit year
char fmt[] = " %m/%d/%y \n %m/%d/%Y ";
strftime( buf, BUFSIZ, fmt, &now );
printf(buf);
return 0;
}
- アプリケーションのユーザーは、アプリケーションで日付を入力するときに 4 桁の西暦を使用して日付を指定する必要があります。
- %x または %c 形式は使用しないでください。この形式が使用されている場合に、strftime 関数と wcsftime 関数を使用するときは、長い形式の日付の取得に # を使用してください。 %x および %c 形式のコードは、デフォルトで下 2 桁の西暦を出力するように設定されています。上記プログラムの fmt の初期化を " %x \n %#x " に変更し、その違いを見てください。
- 時刻の情報は time_t 変数または struct tm に格納し、操作してください。ANSI C には、このタスクで役立つそのほかの時刻関数があります。以下は、これらの関数の一覧と簡単な説明です。詳細については、Visual C++ のマニュアルを参照してください。
- time
: time_t の現在の暦時間を取得します。
- difftime : 2 つの time_t の差を計算します。
- gmtime
: 調整済みグリニッジ平均時 (UTC) で、time_t を struct tm に変換します。
- localtime
: ローカル時間で、time_t を struct tm に変換します。
- asctime
、_wasctime : 渡された struct tm* に対応する文字列を返します。文字列は "DDD MMM dd HH:MM:SS YYYY\n\0" の形式で、常に 26 文字になります。
- ctime
、_wctime : time_t を渡して、文字列形式でローカル時間を返します。 asctime( localtime( time_t_val )) と同一です。
- mktime : struct tm* の値をローカル時間で調整して time_t に格納します。この値は適切な範囲内になるように更新されます。次の例を参照してください。
#include <time.h>
#include <stdio.h>
const int BUFSIZE = 1024;
char buf[BUFSIZE];
int main()
{
struct tm now;
time_t tmp = time(0); // current time
now = *localtime(&tmp);
size_t len = strftime(buf, BUFSIZE, "%#c\n", &now);
now.tm_hour += 48; //jump ahead two days
// should get a bogus hour value
len += strftime(buf+len, BUFSIZE-len, "%#c\n", &now);
mktime(&now); // mktime will correct
strftime(buf+len, BUFSIZE-len, "%#c\n", &now);
printf(buf);
return 0;
}
- _strdate 関数と _wstrdate 関数は ANSI 関数ではありませんが、これらの関数は、9 文字の文字のバッファを生成して、そのバッファへのポインタを受け取ります。出力形式は、"YY/MM/DD" になります。strftime 関数または wcsftime 関数を代わりに使用してください。
西暦 2000 年問題に対応するアプリケーションの開発に関する注意点
詳しくは、